import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { CreateArtworkDto } from './dto/create-artwork.dto';
import { UpdateArtworkDto } from './dto/update-artwork.dto';
import { Artwork, ArtworkDocument } from '../users/schemas/artwork.schema';
import { User, UserDocument, UserRole } from '../users/schemas/user.schema';

@Injectable()
export class ArtworksService {
    constructor(
        @InjectModel(Artwork.name) private artworkModel: Model<ArtworkDocument>,
        @InjectModel(User.name) private userModel: Model<UserDocument>,
    ) { }

    async create(createArtworkDto: CreateArtworkDto & { user_id: string }): Promise<Artwork> {
        const newArtwork = new this.artworkModel({
            ...createArtworkDto,
            like_count: 0,
            view_count: 0,
            is_public: createArtworkDto.is_published || false,
            created_at: new Date(),
            updated_at: new Date(),
        });

        return await newArtwork.save();
    }

    async findAll(page = 1, limit = 10, sort = 'newest'): Promise<{ artworks: Artwork[], total: number }> {
        const skip = (page - 1) * limit;

        // 只返回已发布的作品
        const query = { is_public: true };

        // 设置排序
        let sortOption = {};
        switch (sort) {
            case 'newest':
                sortOption = { created_at: -1 };
                break;
            case 'oldest':
                sortOption = { created_at: 1 };
                break;
            case 'popular':
                sortOption = { view_count: -1 };
                break;
            case 'trending':
                sortOption = { like_count: -1 };
                break;
            default:
                sortOption = { created_at: -1 };
        }

        const artworks = await this.artworkModel
            .find(query)
            .sort(sortOption)
            .skip(skip)
            .limit(limit)
            .exec();

        const total = await this.artworkModel.countDocuments(query).exec();

        return { artworks, total };
    }

    async findFeatured(): Promise<Artwork[]> {
        return await this.artworkModel
            .find({ is_featured: true, is_public: true })
            .sort({ created_at: -1 })
            .limit(8)
            .exec();
    }

    async findOne(id: string): Promise<Artwork> {
        const artwork = await this.artworkModel.findById(id).exec();
        if (!artwork) {
            throw new NotFoundException('作品不存在');
        }

        // 增加浏览次数
        await this.incrementViewCount(id);

        return artwork;
    }

    async update(id: string, userId: string, updateArtworkDto: UpdateArtworkDto): Promise<Artwork> {
        const artwork = await this.artworkModel.findById(id).exec();
        if (!artwork) {
            throw new NotFoundException('作品不存在');
        }

        // 验证是否为作品所有者
        if (artwork.user_id.toString() !== userId) {
            throw new UnauthorizedException('您无权修改此作品');
        }

        // 如果更新包含is_published字段，则更新到is_public字段
        if (updateArtworkDto.is_published !== undefined) {
            updateArtworkDto['is_public'] = updateArtworkDto.is_published;
            delete updateArtworkDto.is_published;
        }

        return await this.artworkModel.findByIdAndUpdate(
            id,
            {
                ...updateArtworkDto,
                updated_at: new Date(),
            },
            { new: true }
        ).exec();
    }

    async remove(id: string, userId: string): Promise<void> {
        const artwork = await this.artworkModel.findById(id).exec();
        if (!artwork) {
            throw new NotFoundException('作品不存在');
        }

        // 检查是否是作品所有者或管理员
        const user = await this.userModel.findById(userId).exec();
        if (artwork.user_id.toString() !== userId && !user.roles.includes(UserRole.ADMIN)) {
            throw new UnauthorizedException('您无权删除此作品');
        }

        await this.artworkModel.findByIdAndDelete(id).exec();

        // 从用户收藏中移除该作品
        await this.userModel.updateMany(
            { favorited_works: id },
            { $pull: { favorited_works: id } }
        ).exec();
    }

    async updatePublishStatus(id: string, userId: string, isPublished: boolean): Promise<Artwork> {
        const artwork = await this.artworkModel.findById(id).exec();
        if (!artwork) {
            throw new NotFoundException('作品不存在');
        }

        // 验证是否为作品所有者
        if (artwork.user_id.toString() !== userId) {
            throw new UnauthorizedException('您无权修改此作品');
        }

        return await this.artworkModel.findByIdAndUpdate(
            id,
            {
                is_public: isPublished,
                updated_at: new Date(),
            },
            { new: true }
        ).exec();
    }

    async updateFeatureStatus(id: string, isFeatured: boolean): Promise<Artwork> {
        const artwork = await this.artworkModel.findById(id).exec();
        if (!artwork) {
            throw new NotFoundException('作品不存在');
        }

        return await this.artworkModel.findByIdAndUpdate(
            id,
            {
                is_featured: isFeatured,
                updated_at: new Date(),
            },
            { new: true }
        ).exec();
    }

    async incrementViewCount(id: string): Promise<void> {
        await this.artworkModel.findByIdAndUpdate(
            id,
            { $inc: { view_count: 1 } }
        ).exec();
    }
}